package com.xm.xmapp.map;

import android.graphics.Point;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;

import com.amap.api.maps.AMap;
import com.amap.api.maps.AMap.InfoWindowAdapter;
import com.amap.api.maps.AMap.OnCameraChangeListener;
import com.amap.api.maps.AMap.OnMapClickListener;
import com.amap.api.maps.AMap.OnMarkerClickListener;
import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.Projection;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.LatLngBounds.Builder;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.xm.xmapp.R;
import com.xm.xmapp.activity.MainActivity;
import com.xm.xmapp.app.MyAppcation;
import com.xm.xmapp.resp.RespAllNetWorkCoordsBean;
import com.xm.xmapp.tool.AndroidTool;


import java.util.ArrayList;
import java.util.List;

public class MapOverlay implements OnCameraChangeListener, OnMarkerClickListener, OnMapClickListener,
		InfoWindowAdapter {

	private ArrayList<ClusterItem> markerListall;// 所有的ClusterItem
	private ArrayList<MyGaodeImageView> clustersMarker;// 聚合点以及网店marker
	private ArrayList<Marker> carMarker;// 小汽车marker
	private AMap aMap;
	private int flag;
	private ClusterClickListener mClusterClickListener;
	private View view;

	public void setOnClusterClickListener(ClusterClickListener mClusterClickListener) {
		this.mClusterClickListener = mClusterClickListener;
	}

	public MapOverlay(AMap aMap) {
		this.aMap = aMap;
		markerListall = new ArrayList<ClusterItem>();
		clustersMarker = new ArrayList<MyGaodeImageView>();
		aMap.setOnCameraChangeListener(this);
		aMap.setOnMarkerClickListener(this);
		aMap.setOnMapClickListener(this);
		aMap.setInfoWindowAdapter(this);
	}

	public void setFlag(int flag) {
		this.flag = flag;
		if (carMarker != null) {
			for (Marker item : carMarker) {
				item.remove();
			}
			carMarker.clear();
		}
	}

	public void setMarkerListall(ArrayList<ClusterItem> mPoints) {

		for (MyGaodeImageView myGaodeImageView : clustersMarker) {
			myGaodeImageView.reMoveMarker();
		}
		clustersMarker.clear();
		markerListall.clear();
		setFlag(flag);
		markerListall.addAll(mPoints);

		float leveltemp = aMap.getCameraPosition().zoom;
		int gridSize = 0;
		if (aMap.getMaxZoomLevel() != leveltemp) {
			gridSize = AndroidTool.dp2px(40);
		}
		resetMarks(getClusterItemListInView(gridSize));

	}

	/**
	 * 视野内的ClusterItem
	 * 
	 * @return
	 */

	private ArrayList<MyGaodeImageView> getClusterItemListInView(int gridSize) {
		Projection projection = aMap.getProjection();
		Point p = null;
		int widthPixels = AndroidTool.getScreenWidth(MyAppcation.getMyAppcation());
		int heightPixels = AndroidTool.getScreenHeight(MyAppcation.getMyAppcation());
		ArrayList<ClusterItem> clusterItemListInView = new ArrayList<ClusterItem>();
		for (ClusterItem mp : markerListall) {// 获取在当前视野内的marker;提高效率
			p = projection.toScreenLocation(mp.getLatLng());
			if (p.x >= 0 && p.y >= 0 && p.x <= widthPixels && p.y <= heightPixels) {// 在当前可观区域内
				clusterItemListInView.add(mp);
			}
		}

		ArrayList<MyGaodeImageView> newClustersMarker = new ArrayList<MyGaodeImageView>();
		for (ClusterItem mp : clusterItemListInView) {
			boolean isIn = false;
			for (MyGaodeImageView cluster : newClustersMarker) {// 判断当前的marker是否在前面marker的聚合范围内,并且每个marker只会聚合一次。
				if (cluster.getBounds().contains(mp.getLatLng())) {
					cluster.addClusterItem(mp);
					isIn = true;
					break;
				}
			}
			if (!isIn) {// 如果没在任何范围内，自己单独形成一个自定义marker。在和后面的marker进行比较
				newClustersMarker.add(new MyGaodeImageView(mp, gridSize, projection, aMap, flag));
			}
		}
		return newClustersMarker;
	}

	/**
	 * 获取视野内的marker 根据聚合算法合成自定义的marker 显示视野内的marker
	 */
	private void resetMarks(ArrayList<MyGaodeImageView> newClustersMarker) {

		for (MyGaodeImageView mmc : newClustersMarker) {// 复用非聚合内的marker
			mmc.setKeyAndOptions();
			ClusterItem item = mmc.getKey();// 获取key值
			if (item != null) {
				for (MyGaodeImageView lastMmc : clustersMarker) {
					if (lastMmc.getKey() == item) {// key值相同，即使是marker可以复用
						mmc.setMarker(lastMmc.getMarker());
					}
				}
				if (mmc.getMarker() == null) {
					mmc.addNewMarker();
				}
			} else {
				mmc.addNewMarker();
			}
		}

		for (MyGaodeImageView myGaodeImageView : clustersMarker) {// 删除上一次没被复用的marker
			Marker marker = myGaodeImageView.getMarker();
			boolean isIn = false;
			for (MyGaodeImageView myGaodeImageView2 : newClustersMarker) {
				if (myGaodeImageView2.getMarker() == marker) {
					isIn = true;
				}
			}
			if (!isIn) {
				marker.remove();
			}
		}
		clustersMarker.clear();
		clustersMarker.addAll(newClustersMarker);
	}

	@Override
	public void onCameraChange(CameraPosition arg0) {

	}

	@Override
	public void onCameraChangeFinish(CameraPosition arg0) {

		float leveltemp = aMap.getCameraPosition().zoom;
		int gridSize = 0;
		if (aMap.getMaxZoomLevel() != leveltemp) {
			gridSize = AndroidTool.dp2px(40);
		}

		ArrayList<MyGaodeImageView> clusterItemListInView = getClusterItemListInView(gridSize);
		resetMarks(clusterItemListInView);

	}


	public void setMClustersCar(ArrayList<ClusterItem> listClusterItem) {

		if (listClusterItem != null) {
			if (carMarker == null) {
				carMarker = new ArrayList<Marker>();
			} else {
				for (Marker marker : carMarker) {
					marker.remove();
				}
				carMarker.clear();
			}
			for (int i = 0, size = listClusterItem.size(); i < size; i++) {
				ClusterItem clusterItem = listClusterItem.get(i);
				LatLng latlng = clusterItem.getLatLng();
				if (latlng.latitude == 0 && latlng.longitude == 0) {
					MarkerOptions markerOptions = new MarkerOptions();
//					markerOptions.anchor(0.5f, 0.5f).icon(BitmapDescriptorFactory.fromResource(R.mipmap.car))
//							.position(latlng);
					Marker marker = aMap.addMarker(markerOptions);
					marker.setObject(clusterItem);
					marker.setSnippet(i + "");
					marker.setVisible(false);
					carMarker.add(marker);
				} else {
					MarkerOptions markerOptions = new MarkerOptions();
//					markerOptions.anchor(0.5f, 0.5f).icon(BitmapDescriptorFactory.fromResource(R.mipmap.car))
//							.position(latlng);
					Marker marker = aMap.addMarker(markerOptions);
					marker.setObject(clusterItem);
					marker.setSnippet(i + "");
					marker.setVisible(true);
					carMarker.add(marker);
				}
			}
			aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(getInclude(listClusterItem), AndroidTool.dp2px(25)), 1000,
					null);
		} else {
			if (carMarker == null) {
				carMarker = new ArrayList<Marker>();
			} else {
				for (Marker marker : carMarker) {
					marker.remove();
				}
				carMarker.clear();
			}
		}

	}

	private LatLngBounds getInclude(ArrayList<ClusterItem> clusterItems) {
		Builder builder = new Builder();
		int size = clusterItems.size();
		for (int i = 0; i < size; i++) {
			if (clusterItems.get(i).getLatLng().latitude != 0 || clusterItems.get(i).getLatLng().longitude != 0)
				builder.include(clusterItems.get(i).getLatLng());
		}
		LatLngBounds bounds = builder.build();
		return bounds;
	}




	@Override
	public boolean onMarkerClick(Marker arg0) {

		Object obj = arg0.getObject();
		if (obj instanceof RespAllNetWorkCoordsBean.PointsBean) {
			ClusterItem clusterItem = (ClusterItem) obj;
				if (mClusterClickListener != null) {
					setMClustersCar(null);
					mClusterClickListener.onMarkerClick(clusterItem);
				}
			return false;
		}

		if (obj instanceof MyGaodeImageView) {
			ArrayList<ClusterItem> clusterItems = ((MyGaodeImageView) obj).getIncludeMarkers();
			aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(getInclude(clusterItems), AndroidTool.dp2px(50)), 1000,
					null);
			return true;
		}
		return false;
	}

	@Override
	public void onMapClick(LatLng arg0) {
		if (mClusterClickListener != null)
		    mClusterClickListener.onMapClick();

	}

	@Override
	public View getInfoContents(Marker arg0) {
		return null;
	}

	@Override
	public View getInfoWindow(Marker arg0) {
		Object obj = arg0.getObject();

		return null;
	}


}
